#include "CameraInvoke.h"
#include <msclr\marshal_cppstd.h>
#include <string>  
#include <iostream>  
using namespace std;
using namespace System;
using namespace System::Collections::Generic;
using namespace msclr::interop;
using namespace FLCamera;

CameraInvoke::CameraInvoke()
{
	//pCameraHik = new CameraHik();
	//vec_pDeviceInfo = new vector<string>();
	/*throw gcnew System::NotImplementedException();*/
}

CameraInvoke::~CameraInvoke()
{
	/*throw gcnew System::NotImplementedException();*/
	//delete pCameraHik;
}

//void MarshalString(System::String^ s, string& os) {
//	using namespace Runtime::InteropServices;
//	const char* chars =
//		(const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
//	os = chars;
//	Marshal::FreeHGlobal(IntPtr((void*)chars));
//}
//bool CameraInvoke::IsConnected() {
//	try {
//		if (pCameraHik == nullptr) 
//		{
//			return false;
//		}
//		else 
//		{
//			return true;
//		}
//	}
//	catch (exception ex) {
//		return false;
//	}
//}
bool CameraInvoke::EnumCameras()
{
	try
	{
		return CameraHik::EnumCameras();
	}
	catch (exception ex) {

	}
}
void CameraInvoke::GetCamerasInfo(List<String^>^ L_cameraInfo/*vector<string>* vec_pDeviceInfo*/) {
	try
	{
		vector<string> vec_pDeviceInfo;
		CameraHik::GetDeviceInfo(&vec_pDeviceInfo);
		for (auto item : vec_pDeviceInfo)
		{
			String^ clrString;

			/*	const char* pcszHello = "hello world";
				clrString = marshal_as<String^>(pcszHello);

				wchar_t* pwszHello = L"hello wide world";
				clrString = marshal_as<String^>(pwszHello);

				bstr_t bstrtHello("hello bstr_t world");
				clrString = marshal_as<String^>(bstrtHello);*/

				//std::string stdHello = "hello from std::string";
			clrString = marshal_as<String^>(item);

			//CString mfcString("hello from CString");
			//clrString = marshal_as<String^>(mfcString);

			//CComBSTR atrBSTR(L"hello from CComBSTR");
			//clrString = marshal_as<String^>(atrBST
			L_cameraInfo->Add(clrString);
			//L_deviceInfo.Add(clrString);
		}

	}
	catch (exception ex) {

	}
}
void CameraInvoke::CloseCameras() {
	try {
		////unsafe
		//{
		//	byte * src = (byte*)sptr.ToPointer();
		//	byte* dst = (byte*)dptr.ToPointer();

		//	if (copylen > 0)
		//	{
		//		// set the source pointer to the end of the string
		//		// to do a reverse copy.
		//		src += copylen - 1;

		//		while (copylen-- > 0)
		//		{
		//			*dst++ = *src--;
		//		}
		//		*dst = 0;
		//	}
		//}
		return CameraHik::CloseAllCameras();
	}
	catch (exception ex) {

	}
}
//std::string ConvertToString(String^ str) {
//	int q = (int)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str);
//	char* p = (char*)q;
//	return std::string(p);
//}
bool CameraInvoke::SwitchCamera(String^ serialNum)
{
	/*String^ clrString = "Original System::String";

	std::string stdHello = marshal_as<std::string>(clrString);
	CString mfcString = marshal_as<CString>(clrString);
	CComBSTR atrBSTR = marshal_as<CComBSTR>(clrString);*/

	/*String^ clrString;

	const char* pcszHello = "hello world";
	clrString = marshal_as<String^>(pcszHello);

	wchar_t* pwszHello = L"hello wide world";
	clrString = marshal_as<String^>(pwszHello);

	bstr_t bstrtHello("hello bstr_t world");
	clrString = marshal_as<String^>(bstrtHello);

	std::string stdHello = "hello from std::string";
	clrString = marshal_as<String^>(stdHello);

	CString mfcString("hello from CString");
	clrString = marshal_as<String^>(mfcString);

	CComBSTR atrBSTR(L"hello from CComBSTR");
	clrString = marshal_as<String^>(atrBST*/

	std::string cliToStd = marshal_as<std::string>(serialNum);
	//String^ c = gcnew String("");
	//c = serialNum;
	//string strSerialNum;
	//MarshalString(c, strSerialNum);
	pCameraHik = CameraHik::FindCamera(cliToStd);

	if (pCameraHik == nullptr) return false;
	return true;
}

bool CameraInvoke::SetExposureTime(double exposureTime)
{
	try {
		if (pCameraHik == nullptr)
			return false;
		//return CameraHik::CloseAllCameras();
		return pCameraHik->SetExposureTime(exposureTime);
	}
	catch (exception ex) {
		return false;
	}
}
float CameraInvoke::GetExposureTime() {
	try {
		if (pCameraHik == nullptr)
			return 0;
		//return CameraHik::CloseAllCameras();
		return pCameraHik->GetExposureTime();
	}
	catch (exception ex) {
		return 0;
	}
}

bool CameraInvoke::SetTriggerMode(unsigned int triggerMode)
{
	try
	{
		if (pCameraHik == nullptr)
			return false;
		//return CameraHik::CloseAllCameras();
		return pCameraHik->SetTriggerMode(triggerMode);
	}
	catch (exception ex) {
		return false;
	}
}

unsigned int CameraInvoke::GetTriggerMode()
{
	try
	{
		if (pCameraHik == nullptr)
			return 0;

		return pCameraHik->GetTriggerMode();
	}
	catch (exception ex) {
		return 0;
	}
}

bool CameraInvoke::SetTriggerSource(unsigned int triggerSource)
{
	try
	{
		if (pCameraHik == nullptr)
			return false;

		return pCameraHik->SetTriggerSource(triggerSource);
	}
	catch (exception ex) {
		return false;
	}
}

unsigned int CameraInvoke::GetTriggerSource()
{
	try
	{
		if (pCameraHik == nullptr)
			return 0;

		return pCameraHik->GetTriggerSource();
	}
	catch (exception ex) {
		return 0;
	}
}

bool CameraInvoke::GrabOneImage([System::Runtime::InteropServices::Out]HalconDotNet::HImage^% image)
{
	try
	{
		unsigned char* pData = pCameraHik->GrabOneImg();
		if (pData == nullptr)
		{
			return false;
		}
		//[MarshalAs(System::Runtime::InteropServices::UnmanagedType::LPArray)]
		//IntPtr ptr = pData;
		//IntPtr ptr = [MarshalAs(System::Runtime::InteropServices::UnmanagedType::LPArray)] pData;
		//[MarshalAs(UnmanagedType.LPArray)] Intptr
		image->GenImage1("byte", pCameraHik->width, pCameraHik->height, System::IntPtr(pData));
		delete pData;
		//image->WriteImage("jpg", 0, "D:\\1.jpg");
		return true;
	}
	catch (exception ex) {
		return false;
	}
}
